package com.djhu.springsimple.beans.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author by zw on 2018/4/16.
 */
public class MatablePropertyValues implements PropertyValues{

    private List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();

    public MatablePropertyValues() {
    }

    public MatablePropertyValues(List<PropertyValue> propertyValues) {
        this.propertyValues = propertyValues;
    }

    public MatablePropertyValues(Map<String,Object> map) {
        for (Map.Entry<String, Object> entry:map.entrySet()){
            PropertyValue propertyValue = new PropertyValue(entry.getKey(),entry.getValue());
            addPropertyValue(propertyValue);
        }
    }

    @Override
    public PropertyValue[] getPropertyValues() {
        return this.propertyValues.toArray(new PropertyValue[this.propertyValues.size()]);
    }

    @Override
    public PropertyValue getPropertyValue(String propertyName) {
        for (PropertyValue propertyValue:propertyValues){
            if (propertyName.equals(propertyValue.getName())){
                return propertyValue;
            }
        }
        return null;
    }

    @Override
    public PropertyValues changesSince(PropertyValues old) {
        MatablePropertyValues changes = new MatablePropertyValues();
        if (old == this) {
            return changes;
        }
        // for each property value in the new set
        for (PropertyValue newPv : this.propertyValues) {
            // if there wasn't an old one, add it
            PropertyValue pvOld = old.getPropertyValue(newPv.getName());
            if (pvOld == null) {
                changes.addPropertyValue(newPv);
            }
            else if (!pvOld.equals(newPv)) {
                // it's changed
                changes.addPropertyValue(newPv);
            }
        }
        return changes;
    }

    @Override
    public PropertyValues addPropertyValue(PropertyValue newPv) {
        for (int i = 0;i<this.propertyValues.size();i++){
            if (newPv.getName().equals(propertyValues.get(i).getName())){

                if (newPv.getValue() instanceof Mergeable){
                        Mergeable mergeable = (Mergeable)(newPv.getValue());
                        if (mergeable.isMerge()){
                            Object newValue = mergeable.merge(propertyValues.get(i).getValue());
                            propertyValues.get(i).setValue(newValue);
                        }
                }else {
                    propertyValues.get(i).setValue(newPv.getName());
                }
            }
            return this;
        }
        this.propertyValues.add(newPv);
        return this;
    }



    @Override
    public boolean contains(String propertyName) {
        for (PropertyValue propertyValue:propertyValues){
            if (propertyValue.getName().equals(propertyName)){
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean isEmpty() {
        return propertyValues.isEmpty();
    }
}